{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://mp.weixin.qq.com/s?__biz=MzkxOTQzNDEzOA==&mid=2247488004&idx=1&sn=1078120278d25b64b41a4b4229a5fd5f&chksm=c1a374f1f6d4fde7f61cdd127956ea963f733c2da355d54468f45461fc685a9c693257036c9f&scene=178&cur_album_id=2757756098094497794#rd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.64898713e-02 2.41668086e-07 7.55963162e-08 1.03008565e-02\n",
      " 1.33346885e-01 3.09430810e-07 2.28521259e-07 1.88127446e-01\n",
      " 8.78178019e-08 1.06451772e-01 3.78274251e-02 5.97487091e-07\n",
      " 1.93800585e-02 1.16900117e-01 7.06322650e-07 1.64477192e-01\n",
      " 1.21290536e-02 1.00386519e-02 8.77060438e-02 8.68223815e-02]\n",
      "0.9149939890195917\n",
      "Mean                                             0.054%\n",
      "Annualized Mean                                  13.63%\n",
      "Variance                                        0.0088%\n",
      "Annualized Variance                               2.22%\n",
      "Semi-Variance                                   0.0045%\n",
      "Annualized Semi-Variance                          1.14%\n",
      "Standard Deviation                                0.94%\n",
      "Annualized Standard Deviation                    14.90%\n",
      "Semi-Deviation                                    0.67%\n",
      "Annualized Semi-Deviation                        10.69%\n",
      "Mean Absolute Deviation                           0.61%\n",
      "CVaR at 95%                                       2.16%\n",
      "EVaR at 95%                                       4.63%\n",
      "Worst Realization                                 8.58%\n",
      "CDaR at 95%                                      13.92%\n",
      "MAX Drawdown                                     33.58%\n",
      "Average Drawdown                                  2.87%\n",
      "EDaR at 95%                                      19.60%\n",
      "First Lower Partial Moment                        0.30%\n",
      "Ulcer Index                                       0.047\n",
      "Gini Mean Difference                              0.91%\n",
      "Value at Risk at 95%                              1.34%\n",
      "Drawdown at Risk at 95%                          10.58%\n",
      "Entropic Risk Measure at 95%                       3.00\n",
      "Fourth Central Moment                         0.000016%\n",
      "Fourth Lower Partial Moment                   0.000007%\n",
      "Skew                                            -0.0019\n",
      "Kurtosis                                          20.32\n",
      "Sharpe Ratio                                      0.058\n",
      "Annualized Sharpe Ratio                            0.91\n",
      "Sortino Ratio                                     0.080\n",
      "Annualized Sortino Ratio                           1.28\n",
      "Mean Absolute Deviation Ratio                     0.089\n",
      "First Lower Partial Moment Ratio                   0.18\n",
      "Value at Risk Ratio at 95%                        0.040\n",
      "CVaR Ratio at 95%                                 0.025\n",
      "Entropic Risk Measure Ratio at 95%              0.00018\n",
      "EVaR Ratio at 95%                                 0.012\n",
      "Worst Realization Ratio                          0.0063\n",
      "Drawdown at Risk Ratio at 95%                    0.0051\n",
      "CDaR Ratio at 95%                                0.0039\n",
      "Calmar Ratio                                     0.0016\n",
      "Average Drawdown Ratio                            0.019\n",
      "EDaR Ratio at 95%                                0.0028\n",
      "Ulcer Index Ratio                                 0.012\n",
      "Gini Mean Difference Ratio                        0.059\n",
      "Effective Number of Assets            8.109222967681443\n",
      "Assets Number                                        20\n",
      "dtype: object\n",
      "{'add_constraints': None, 'add_objective': None, 'budget': 1.0, 'cdar_beta': 0.95, 'covariance_uncertainty_set_estimator': None, 'cvar_beta': 0.95, 'edar_beta': 0.95, 'efficient_frontier_size': None, 'evar_beta': 0.95, 'groups': None, 'l1_coef': 0.0, 'l2_coef': 0.0, 'left_inequality': None, 'linear_constraints': None, 'management_fees': 0.0, 'max_average_drawdown': None, 'max_budget': None, 'max_cdar': None, 'max_cvar': None, 'max_edar': None, 'max_evar': None, 'max_first_lower_partial_moment': None, 'max_gini_mean_difference': None, 'max_long': None, 'max_max_drawdown': None, 'max_mean_absolute_deviation': None, 'max_semi_deviation': None, 'max_semi_variance': None, 'max_short': None, 'max_standard_deviation': None, 'max_tracking_error': None, 'max_turnover': None, 'max_ulcer_index': None, 'max_variance': None, 'max_weights': 1.0, 'max_worst_realization': None, 'min_acceptable_return': None, 'min_budget': None, 'min_return': None, 'min_weights': 0.0, 'mu_uncertainty_set_estimator': None, 'objective_function': MAXIMIZE_RATIO, 'overwrite_expected_return': None, 'portfolio_params': None, 'previous_weights': None, 'prior_estimator__covariance_estimator': None, 'prior_estimator__investment_horizon': None, 'prior_estimator__is_log_normal': False, 'prior_estimator__mu_estimator__alpha': 0.2, 'prior_estimator__mu_estimator__window_size': None, 'prior_estimator__mu_estimator': EWMu(), 'prior_estimator': EmpiricalPrior(mu_estimator=EWMu()), 'raise_on_failure': True, 'right_inequality': None, 'risk_aversion': 1.0, 'risk_free_rate': 0.0, 'risk_measure': Variance, 'save_problem': False, 'scale_constraints': None, 'scale_objective': None, 'solver': 'CLARABEL', 'solver_params': None, 'transaction_costs': 0.0}\n",
      "[-1.27058324e-12 -2.82185348e-13  1.43592854e-11  6.50331478e-11\n",
      "  2.91498749e-01  4.30238812e-11  2.06832127e-11  5.12558189e-11\n",
      "  5.96187217e-11  2.92863748e-10  8.06833457e-11  3.59886052e-01\n",
      "  5.23710030e-12  5.32308068e-11  2.48282553e-11  3.48615197e-01\n",
      "  3.69763042e-13  3.05435172e-11  8.36884417e-12  3.39254726e-10]\n",
      "Mean                                     0.050%\n",
      "Annualized Mean                          12.64%\n",
      "Variance                                0.0082%\n",
      "Annualized Variance                       2.06%\n",
      "Semi-Variance                           0.0042%\n",
      "Annualized Semi-Variance                  1.07%\n",
      "Standard Deviation                        0.90%\n",
      "Annualized Standard Deviation            14.35%\n",
      "Semi-Deviation                            0.65%\n",
      "Annualized Semi-Deviation                10.33%\n",
      "Mean Absolute Deviation                   0.59%\n",
      "CVaR at 95%                               2.08%\n",
      "EVaR at 95%                               4.55%\n",
      "Worst Realization                         8.57%\n",
      "CDaR at 95%                              14.35%\n",
      "MAX Drawdown                             29.25%\n",
      "Average Drawdown                          3.27%\n",
      "EDaR at 95%                              18.11%\n",
      "First Lower Partial Moment                0.30%\n",
      "Ulcer Index                               0.051\n",
      "Gini Mean Difference                      0.89%\n",
      "Value at Risk at 95%                      1.27%\n",
      "Drawdown at Risk at 95%                  11.93%\n",
      "Entropic Risk Measure at 95%               3.00\n",
      "Fourth Central Moment                 0.000013%\n",
      "Fourth Lower Partial Moment           0.000007%\n",
      "Skew                                      -0.13\n",
      "Kurtosis                                  19.18\n",
      "Sharpe Ratio                              0.055\n",
      "Annualized Sharpe Ratio                    0.88\n",
      "Sortino Ratio                             0.077\n",
      "Annualized Sortino Ratio                   1.22\n",
      "Mean Absolute Deviation Ratio             0.085\n",
      "First Lower Partial Moment Ratio           0.17\n",
      "Value at Risk Ratio at 95%                0.040\n",
      "CVaR Ratio at 95%                         0.024\n",
      "Entropic Risk Measure Ratio at 95%      0.00017\n",
      "EVaR Ratio at 95%                         0.011\n",
      "Worst Realization Ratio                  0.0059\n",
      "Drawdown at Risk Ratio at 95%            0.0042\n",
      "CDaR Ratio at 95%                        0.0035\n",
      "Calmar Ratio                             0.0017\n",
      "Average Drawdown Ratio                    0.015\n",
      "EDaR Ratio at 95%                        0.0028\n",
      "Ulcer Index Ratio                        0.0099\n",
      "Gini Mean Difference Ratio                0.057\n",
      "Portfolios Number                             5\n",
      "Avg nb of Assets per Portfolio             20.0\n",
      "dtype: object\n"
     ]
    }
   ],
   "source": [
    "from sklearn import set_config\n",
    "from sklearn.model_selection import (\n",
    "    GridSearchCV,\n",
    "    KFold,\n",
    "    RandomizedSearchCV,\n",
    "    train_test_split,\n",
    ")\n",
    "from sklearn.pipeline import Pipeline\n",
    "from scipy.stats import loguniform\n",
    "\n",
    "from skfolio import RatioMeasure, RiskMeasure\n",
    "from skfolio.datasets import load_factors_dataset, load_sp500_dataset\n",
    "from skfolio.model_selection import (\n",
    "    CombinatorialPurgedCV,\n",
    "    WalkForward,\n",
    "    cross_val_predict,\n",
    ")\n",
    "from skfolio.moments import (\n",
    "    DenoiseCovariance,\n",
    "    DetoneCovariance,\n",
    "    EWMu,\n",
    "    GerberCovariance,\n",
    "    ShrunkMu,\n",
    ")\n",
    "from skfolio.optimization import (\n",
    "    MeanRisk,\n",
    "    NestedClustersOptimization,\n",
    "    ObjectiveFunction,\n",
    "    RiskBudgeting,\n",
    ")\n",
    "from skfolio.pre_selection import SelectKExtremes\n",
    "from skfolio.preprocessing import prices_to_returns\n",
    "from skfolio.prior import BlackLitterman, EmpiricalPrior, FactorModel\n",
    "from skfolio.uncertainty_set import BootstrapMuUncertaintySet\n",
    "\n",
    "\n",
    "# 加载数据集\n",
    "prices = load_sp500_dataset()\n",
    "\n",
    "\n",
    "# 训练/测试数据划分\n",
    "X = prices_to_returns(prices)\n",
    "X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)\n",
    "\n",
    "\n",
    "# 训练最小风险模型\n",
    "model = MeanRisk()\n",
    "model.fit(X_train)\n",
    "print(model.weights_)\n",
    "\n",
    "\n",
    "# 对测试集进行预测\n",
    "portfolio = model.predict(X_test)\n",
    "print(portfolio.annualized_sharpe_ratio)\n",
    "print(portfolio.summary())\n",
    "\n",
    "\n",
    "# 最大索提诺比率\n",
    "model = MeanRisk(\n",
    "    objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n",
    "    risk_measure=RiskMeasure.SEMI_VARIANCE,\n",
    ")\n",
    "\n",
    "# 去噪协方差和缩小的预期回报\n",
    "model = MeanRisk(\n",
    "    objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n",
    "    prior_estimator=EmpiricalPrior(\n",
    "        mu_estimator=ShrunkMu(), covariance_estimator=DenoiseCovariance()\n",
    "    ),\n",
    ")\n",
    "\n",
    "# 预期回报的不确定性\n",
    "model = MeanRisk(\n",
    "    objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n",
    "    mu_uncertainty_set_estimator=BootstrapMuUncertaintySet(),\n",
    ")\n",
    "\n",
    "# 权重限制和交易成本\n",
    "model = MeanRisk(\n",
    "    min_weights={\"AAPL\": 0.10, \"JPM\": 0.05},\n",
    "    max_weights=0.8,\n",
    "    transaction_costs={\"AAPL\": 0.0001, \"RRC\": 0.0002},\n",
    "    groups=[\n",
    "        [\"Equity\"] * 3 + [\"Fund\"] * 5 + [\"Bond\"] * 12,\n",
    "        [\"US\"] * 2 + [\"Europe\"] * 8 + [\"Japan\"] * 10,\n",
    "    ],\n",
    "    linear_constraints=[\n",
    "        \"Equity <= 0.5 * Bond\",\n",
    "        \"US >= 0.1\",\n",
    "        \"Europe >= 0.5 * Fund\",\n",
    "        \"Japan <= 1\",\n",
    "    ],\n",
    ")\n",
    "model.fit(X_train)\n",
    "\n",
    "\n",
    "# 参数网格搜索\n",
    "model = MeanRisk(\n",
    "    objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n",
    "    risk_measure=RiskMeasure.VARIANCE,\n",
    "    prior_estimator=EmpiricalPrior(mu_estimator=EWMu(alpha=0.2)),\n",
    ")\n",
    "\n",
    "print(model.get_params(deep=True))\n",
    "\n",
    "gs = GridSearchCV(\n",
    "    estimator=model,\n",
    "    cv=KFold(n_splits=5, shuffle=False),\n",
    "    n_jobs=-1,\n",
    "    param_grid={\n",
    "        \"risk_measure\": [\n",
    "            RiskMeasure.VARIANCE,\n",
    "            RiskMeasure.CVAR,\n",
    "            RiskMeasure.VARIANCE.CDAR,\n",
    "        ],\n",
    "        \"prior_estimator__mu_estimator__alpha\": [0.05, 0.1, 0.2, 0.5],\n",
    "    },\n",
    ")\n",
    "gs.fit(X)\n",
    "\n",
    "best_model = gs.best_estimator_\n",
    "\n",
    "print(best_model.weights_)\n",
    "\n",
    "\n",
    "# K 折交叉验证\n",
    "model = MeanRisk()\n",
    "mmp = cross_val_predict(model, X_test, cv=KFold(n_splits=5))\n",
    "# mmp is the predicted MultiPeriodPortfolio object composed of 5 Portfolios (1 per testing fold)\n",
    "\n",
    "mmp.plot_cumulative_returns()\n",
    "print(mmp.summary())\n",
    "#组合清除交叉验证"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "4broker",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
